#ifndef JCR_UTILS_H
#define JCR_UTILS_H

#include <QList>
#include <QUrl>
#include <QMap>
#include <gumbo.h>
#include <QObject>

#ifdef DEBUG_VAR
#undef DEBUG_VAR
#endif
#define DEBUG_VAR(VAR) qDebug() << "@"__FUNCTION__<< ":" << __LINE__ << "{" << #VAR << "=" << VAR <<"}";

#ifndef DEBUG_WHERE
#define DEBUG_WHERE qDebug() << __FILE__ << "@" << __FUNCTION__ << "#" << __LINE__;
#endif

typedef QMap<std::string, std::string> StdStringMap;
Q_DECLARE_METATYPE(StdStringMap)

namespace Jcr
{

template <class T>
void safeRelease(T** obj)
{
    if (*obj) {
        delete *obj;
        *obj = nullptr;
    }
}

template <class T, typename Container = QList<T> >
void safeRelease(Container& objs)
{
    foreach (T* obj, objs) {
        if (obj) {
            delete obj;
            obj = nullptr;
        }
    }
}

template <class T>
void initOnce(T** obj)
{
    if (*obj == nullptr)
        *obj = new T();
}

class Utils
{
public:
    static QString fileNameFromUrl(const QUrl& url);
    static QString fileExtFromUrl(const QUrl& url);
    static QString localFileName(const QString& brand, const QString& model, const QString& saveName);
    static QString makeDirectory(const QString& brand, const QString& model);
    static bool fileExists(const QUrl& url, const QString& saveDir, const QString& saveName, QString* savePath = nullptr);
    static void runByThread(QObject* object);

    static void write(const QString& file, const QByteArray& data);
    static QByteArray read(const QString& file);

    static std::string gbk2Utf8(const std::string& strGBK);

    static QUrl modelParametersUrl(const QUrl& modelUrl);
    static QUrl bigImageLink(const QUrl& thumbnailUrl);

    static bool isGif(const QUrl& url);
    static bool isPicture(const QUrl& url);

    static void locate(const QString& path);

    // the count of sub dirs
    static int dirCount(const QString& dir);
    static int fileCount(const QString& dir);

private:
    Utils();
};

class GumboUtils
{
public:
    static std::string getNodeText(GumboNode* node);
    static void getAttributeValue(GumboNode* node, GumboTag tag,
                                  const char* attr, std::list<std::string>& values);
    static bool isImageLink(const std::string& link);
    static bool isVideoLink(const std::string& link);
};

}
#endif // UTILS_H
